package hydrap2p.proxy.manager;
import java.util.Map;
import java.util.TreeMap;

import hydrap2p.ServiceLocation;
import hydrap2p.logging.Level;

public class NetworkOutstandingCallbacks {
	private static Map<ServiceLocation, ServiceLocation> outstanding = new TreeMap<ServiceLocation, ServiceLocation>();
	
	public static void prepareFor(ServiceLocation key)
	{
		synchronized(outstanding)
		{
			if (!outstanding.containsKey(key))
				outstanding.put(key, null);
			else
				ProxyLogging.log(Level.MISHAP, "ProxyManager - NetworkingOutstandingCallbacks", "Weird state, trying to compare twice for the same callback request: "+key);
		}
	}
	
	public static ServiceLocation waitFor(ServiceLocation key)
	{
		//ProxyLogging.log(Level.DEBUG, "ProxyManager - NetworkingOutstandingCallbacks", "Waiting for response from callback "+key);
		synchronized(outstanding)
		{
			while (outstanding.containsKey(key))
			{
				try {
					outstanding.wait();
				} catch (InterruptedException e) {
					// someone wants to die
				}
				// if we're still waiting
				if (outstanding.containsKey(key))
				{	// and the answer is done
					if (outstanding.get(key)!=null)
					{
						//ProxyLogging.log(Level.DEBUG, "ProxyManager - NetworkingOutstandingCallbacks", "Finished waiting for response from callback "+key+" and got port "+outstanding.get(key));
						ServiceLocation ret=outstanding.get(key);
						outstanding.remove(key);
						return ret;
					}
				}
			}
		}
		//ProxyLogging.log(Level.DEBUG, "ProxyManager - NetworkingOutstandingCallbacks", "Finished waiting for response from callback "+key+" and didn't get a port");
		
		return null;
	}
	
	public static void errorFor(ServiceLocation key)
	{
		//ProxyLogging.log(Level.INFO, "ProxyManager - NetworkingOutstandingCallbacks", "Received error for callback request "+key);
		synchronized(outstanding)
		{
			outstanding.remove(key);
			outstanding.notifyAll();
		}
	}
	
	public static void finishFor(ServiceLocation key, ServiceLocation value)
	{
		//ProxyLogging.log(Level.DEBUG, "ProxyManager - NetworkingOutstandingCallbacks", "Received response for callback request "+key+", winning "+value);
		synchronized(outstanding)
		{
			if (outstanding.containsKey(key))
			{
				outstanding.put(key, value);
				outstanding.notifyAll();
			}
		}
		
	}
	
}
